-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Add complete ObjectFileJSON support for sections. #129916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Sections now support specifying: - user IDs - file offset/size - alignment - flags - bool values for fake, encrypted and thread specific sections
|
@llvm/pr-subscribers-lldb Author: Greg Clayton (clayborg) ChangesSections now support specifying:
Full diff: https://github.com/llvm/llvm-project/pull/129916.diff 4 Files Affected:
diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h
index 17b3cb454949f..f0f5a0b3499c0 100644
--- a/lldb/include/lldb/Core/Section.h
+++ b/lldb/include/lldb/Core/Section.h
@@ -101,14 +101,25 @@ class SectionList {
};
struct JSONSection {
+ std::optional<lldb::user_id_t> user_id;
std::string name;
std::optional<lldb::SectionType> type;
std::optional<uint64_t> address;
std::optional<uint64_t> size;
+ std::optional<uint64_t> file_offset;
+ std::optional<uint64_t> file_size;
+ std::optional<uint64_t> log2align;
+ std::optional<uint64_t> flags;
+
// Section permissions;
std::optional<bool> read;
std::optional<bool> write;
std::optional<bool> execute;
+
+ std::optional<bool> fake;
+ std::optional<bool> encrypted;
+ std::optional<bool> thread_specific;
+
std::vector<JSONSection> subsections;
};
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 608e2a5fc3093..b3a0814750aa5 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -160,10 +160,9 @@ const char *Section::GetTypeAsCString() const {
}
Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
- user_id_t sect_id, ConstString name,
- SectionType sect_type, addr_t file_addr, addr_t byte_size,
- lldb::offset_t file_offset, lldb::offset_t file_size,
- uint32_t log2align, uint32_t flags,
+ user_id_t sect_id, ConstString name, SectionType sect_type,
+ addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
+ lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
uint32_t target_byte_size /*=1*/)
: ModuleChild(module_sp), UserID(sect_id), Flags(flags),
m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
@@ -171,15 +170,14 @@ Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
- m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
-}
+ m_executable(false), m_relocated(false),
+ m_target_byte_size(target_byte_size) {}
Section::Section(const lldb::SectionSP &parent_section_sp,
const ModuleSP &module_sp, ObjectFile *obj_file,
- user_id_t sect_id, ConstString name,
- SectionType sect_type, addr_t file_addr, addr_t byte_size,
- lldb::offset_t file_offset, lldb::offset_t file_size,
- uint32_t log2align, uint32_t flags,
+ user_id_t sect_id, ConstString name, SectionType sect_type,
+ addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
+ lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
uint32_t target_byte_size /*=1*/)
: ModuleChild(module_sp), UserID(sect_id), Flags(flags),
m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
@@ -187,7 +185,8 @@ Section::Section(const lldb::SectionSP &parent_section_sp,
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
- m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
+ m_executable(false), m_relocated(false),
+ m_target_byte_size(target_byte_size) {
if (parent_section_sp)
m_parent_wp = parent_section_sp;
}
@@ -469,7 +468,6 @@ bool Section::ContainsOnlyDebugInfo() const {
return false;
}
-
#pragma mark SectionList
SectionList &SectionList::operator=(const SectionList &rhs) {
@@ -554,8 +552,7 @@ SectionSP SectionList::GetSectionAtIndex(size_t idx) const {
return sect_sp;
}
-SectionSP
-SectionList::FindSectionByName(ConstString section_dstr) const {
+SectionSP SectionList::FindSectionByName(ConstString section_dstr) const {
SectionSP sect_sp;
// Check if we have a valid section string
if (section_dstr && !m_sections.empty()) {
@@ -693,7 +690,14 @@ bool fromJSON(const llvm::json::Value &value,
o.map("address", section.address) && o.map("size", section.size) &&
o.map("read", section.read) && o.map("write", section.write) &&
o.map("execute", section.execute) &&
- o.mapOptional("subsections", section.subsections);
+ o.mapOptional("subsections", section.subsections) &&
+ o.map("user_id", section.user_id) &&
+ o.map("file_offset", section.file_offset) &&
+ o.map("file_size", section.file_size) &&
+ o.map("log2align", section.log2align) &&
+ o.map("flags", section.flags) && o.map("fake", section.fake) &&
+ o.map("encrypted", section.encrypted) &&
+ o.map("thread_specific", section.thread_specific);
}
bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type,
diff --git a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp
index 0f9676b836b50..cb8ba05d461d4 100644
--- a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp
+++ b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp
@@ -179,39 +179,35 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
return;
m_sections_up = std::make_unique<SectionList>();
- lldb::user_id_t id = 1;
+ lldb::user_id_t id = 0;
for (const auto &json_section : m_sections) {
auto make_section = [this, &id](const JSONSection §ion,
SectionSP parent_section_sp =
nullptr) -> SectionSP {
SectionSP section_sp;
+ auto sect_id = section.user_id.value_or(id + 1);
+ if (!section.user_id.has_value())
+ ++id;
+ const auto name = ConstString(section.name);
+ const auto sect_type = section.type.value_or(eSectionTypeCode);
+ const auto vm_addr = section.address.value_or(0);
+ const auto vm_size = section.size.value_or(0);
+ const auto file_offset = section.file_offset.value_or(0);
+ const auto file_size = section.file_size.value_or(0);
+ const auto log2align = section.log2align.value_or(0);
+ const auto flags = section.flags.value_or(0);
if (parent_section_sp) {
section_sp = std::make_shared<Section>(
- parent_section_sp, GetModule(), this,
- /*sect_id=*/id++,
- /*name=*/ConstString(section.name),
- /*sect_type=*/section.type.value_or(eSectionTypeCode),
- /*file_vm_addr=*/section.address.value_or(0) -
- parent_section_sp->GetFileAddress(),
- /*vm_size=*/section.size.value_or(0),
- /*file_offset=*/0,
- /*file_size=*/0,
- /*log2align=*/0,
- /*flags=*/0);
+ parent_section_sp, GetModule(), this, sect_id, name, sect_type,
+ vm_addr - parent_section_sp->GetFileAddress(), vm_size, file_offset,
+ file_size, log2align, flags);
} else {
section_sp = std::make_shared<Section>(
- GetModule(), this,
- /*sect_id=*/id++,
- /*name=*/ConstString(section.name),
- /*sect_type=*/section.type.value_or(eSectionTypeCode),
- /*file_vm_addr=*/section.address.value_or(0),
- /*vm_size=*/section.size.value_or(0),
- /*file_offset=*/0,
- /*file_size=*/0,
- /*log2align=*/0,
- /*flags=*/0);
+ GetModule(), this, sect_id, name, sect_type, vm_addr, vm_size,
+ file_offset, file_size, log2align, flags);
}
+ // Set permissions
uint32_t permissions = 0;
if (section.read.value_or(0))
permissions |= lldb::ePermissionsReadable;
@@ -221,6 +217,9 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
permissions |= lldb::ePermissionsExecutable;
if (permissions)
section_sp->SetPermissions(permissions);
+ section_sp->SetIsFake(section.fake.value_or(false));
+ section_sp->SetIsEncrypted(section.encrypted.value_or(false));
+ section_sp->SetIsThreadSpecific(section.thread_specific.value_or(false));
return section_sp;
};
auto section_sp = make_section(json_section);
diff --git a/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py b/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py
index 510788b43d0db..03c0d11a858a7 100644
--- a/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py
+++ b/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py
@@ -64,6 +64,7 @@ def test_module(self):
foo_file_addr = TEXT_file_addr + 0x100
bar_file_addr = DATA_file_addr + 0x10
TEXT_size = 0x222
+ text_size = 0x20
DATA_size = 0x333
foo_size = 0x11
bar_size = 0x22
@@ -74,10 +75,22 @@ def test_module(self):
"type": "sharedlibrary",
"sections": [
{
+ "user_id": 0x100,
+ "name": "__PAGEZERO",
+ "type": "container",
+ "address": 0,
+ "size": 0x100000000,
+ "flags": 0x101
+ },
+ {
+ "user_id": 0x200,
"name": "__TEXT",
"type": "container",
"address": TEXT_file_addr,
"size": TEXT_size,
+ "flags": 0x202,
+ "file_offset": 0,
+ "file_size": TEXT_size,
"read": True,
"write": False,
"execute": True,
@@ -86,10 +99,29 @@ def test_module(self):
"name": "__text",
"type": "code",
"address": TEXT_file_addr,
- "size": TEXT_size,
+ "size": text_size,
+ "log2align": 2,
"read": True,
"write": False,
"execute": True,
+ },
+ {
+ "name": "__fake",
+ "address": TEXT_file_addr + 1 * text_size,
+ "size": text_size,
+ "fake": True
+ },
+ {
+ "name": "__encrypted",
+ "address": TEXT_file_addr + 2 * text_size,
+ "size": text_size,
+ "encrypted": True
+ },
+ {
+ "name": "__tls",
+ "address": TEXT_file_addr + 2 * text_size,
+ "size": text_size,
+ "thread_specific": True
}
],
},
@@ -101,6 +133,9 @@ def test_module(self):
"read": True,
"write": True,
"execute": False,
+ "flags": 0x303,
+ "file_offset": DATA_file_addr - TEXT_file_addr,
+ "file_size": DATA_size,
},
],
"symbols": [
@@ -127,21 +162,34 @@ def test_module(self):
TEXT_section = module.GetSectionAtIndex(0)
self.assertTrue(TEXT_section.IsValid())
+ self.assertEqual(TEXT_section.GetName(), "__PAGEZERO")
+ self.assertEqual(TEXT_section.file_addr, 0)
+ self.assertEqual(TEXT_section.size, 0x100000000)
+ self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
+ self.assertEqual(TEXT_section.GetNumSubSections(), 0)
+ text_permissions = TEXT_section.GetPermissions()
+ self.assertFalse((text_permissions & lldb.ePermissionsReadable) != 0)
+ self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
+ self.assertFalse((text_permissions & lldb.ePermissionsExecutable) != 0)
+
+ TEXT_section = module.GetSectionAtIndex(1)
+ self.assertTrue(TEXT_section.IsValid())
self.assertEqual(TEXT_section.GetName(), "__TEXT")
self.assertEqual(TEXT_section.file_addr, TEXT_file_addr)
self.assertEqual(TEXT_section.size, TEXT_size)
+ self.assertEqual(TEXT_section.file_offset, 0)
+ self.assertEqual(TEXT_section.file_size, TEXT_size)
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
- self.assertEqual(TEXT_section.GetNumSubSections(), 1)
+ self.assertEqual(TEXT_section.GetNumSubSections(), 4)
text_permissions = TEXT_section.GetPermissions()
self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0)
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
text_section = TEXT_section.GetSubSectionAtIndex(0)
- self.assertTrue(text_section.IsValid())
self.assertEqual(text_section.GetName(), "__text")
- self.assertEqual(text_section.file_addr, TEXT_file_addr)
- self.assertEqual(text_section.size, TEXT_size)
+ self.assertEqual(text_section.size, text_size)
+ self.assertEqual(text_section.GetAlignment(), 4)
self.assertEqual(text_section.GetSectionType(), lldb.eSectionTypeCode)
self.assertEqual(text_section.GetNumSubSections(), 0)
text_permissions = text_section.GetPermissions()
@@ -149,11 +197,13 @@ def test_module(self):
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
- DATA_section = module.GetSectionAtIndex(1)
+ DATA_section = module.GetSectionAtIndex(2)
self.assertTrue(DATA_section.IsValid())
self.assertEqual(DATA_section.GetName(), "__DATA")
self.assertEqual(DATA_section.file_addr, DATA_file_addr)
self.assertEqual(DATA_section.size, DATA_size)
+ self.assertEqual(DATA_section.file_offset, DATA_file_addr - TEXT_file_addr)
+ self.assertEqual(DATA_section.file_size, DATA_size)
self.assertEqual(DATA_section.GetSectionType(), lldb.eSectionTypeData)
data_permissions = DATA_section.GetPermissions()
self.assertTrue((data_permissions & lldb.ePermissionsReadable) != 0)
@@ -170,6 +220,19 @@ def test_module(self):
self.assertEqual(bar_symbol.addr.GetFileAddress(), bar_file_addr)
self.assertEqual(bar_symbol.GetSize(), bar_size)
+ # Verify the user_ids and flags are set correctly since there is no API
+ # for this on lldb.SBSection
+ self.expect("target modules dump sections c.json",
+ substrs = [
+ "0x0000000000000100 container [0x0000000000000000-0x0000000100000000) --- 0x00000000 0x00000000 0x00000101 c.json.__PAGEZERO",
+ "0x0000000000000200 container [0x0000000100000000-0x0000000100000222) r-x 0x00000000 0x00000222 0x00000202 c.json.__TEXT",
+ "0x0000000000000001 code [0x0000000100000000-0x0000000100000020) r-x 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__text",
+ "0x0000000000000002 code [0x0000000100000020-0x0000000100000040) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__fake",
+ "0x0000000000000003 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__encrypted",
+ "0x0000000000000004 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__tls",
+ "0x0000000000000005 data [0x0000000100001000-0x0000000100001333) rw- 0x00001000 0x00000333 0x00000303 c.json.__DATA"
+ ])
+
error = target.SetSectionLoadAddress(TEXT_section, TEXT_file_addr + slide)
self.assertSuccess(error)
error = target.SetSectionLoadAddress(DATA_section, DATA_file_addr + slide)
|
JDevlieghere
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also update docs/use/symbolfilejson.rst? Doesn't need to be in this PR.
lldb/source/Core/Section.cpp
Outdated
| o.map("user_id", section.user_id) && | ||
| o.map("file_offset", section.file_offset) && | ||
| o.map("file_size", section.file_size) && | ||
| o.map("log2align", section.log2align) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just alignment instead of log2align?
JDevlieghere
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
You can test this locally with the following command:darker --check --diff -r 024362f413dbfcf8188003762c9cc299f274d76e...48fec8f9fd6fd19426943f0daf3eb6fcaf6fe8f0 lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.pyView the diff from darker here.--- TestObjectFileJSON.py 2025-03-07 23:29:50.000000 +0000
+++ TestObjectFileJSON.py 2025-03-07 23:33:27.931147 +0000
@@ -78,13 +78,13 @@
"user_id": 0x100,
"name": "__PAGEZERO",
"type": "container",
"address": 0,
"size": 0x100000000,
- "flags": 0x101
- },
- {
+ "flags": 0x101,
+ },
+ {
"user_id": 0x200,
"name": "__TEXT",
"type": "container",
"address": TEXT_file_addr,
"size": TEXT_size,
@@ -107,24 +107,24 @@
},
{
"name": "__fake",
"address": TEXT_file_addr + 1 * text_size,
"size": text_size,
- "fake": True
+ "fake": True,
},
{
"name": "__encrypted",
"address": TEXT_file_addr + 2 * text_size,
"size": text_size,
- "encrypted": True
+ "encrypted": True,
},
{
"name": "__tls",
"address": TEXT_file_addr + 2 * text_size,
"size": text_size,
- "thread_specific": True
- }
+ "thread_specific": True,
+ },
],
},
{
"name": "__DATA",
"type": "data",
@@ -220,20 +220,22 @@
self.assertEqual(bar_symbol.addr.GetFileAddress(), bar_file_addr)
self.assertEqual(bar_symbol.GetSize(), bar_size)
# Verify the user_ids and flags are set correctly since there is no API
# for this on lldb.SBSection
- self.expect("target modules dump sections c.json",
- substrs = [
+ self.expect(
+ "target modules dump sections c.json",
+ substrs=[
"0x0000000000000100 container [0x0000000000000000-0x0000000100000000) --- 0x00000000 0x00000000 0x00000101 c.json.__PAGEZERO",
"0x0000000000000200 container [0x0000000100000000-0x0000000100000222) r-x 0x00000000 0x00000222 0x00000202 c.json.__TEXT",
"0x0000000000000001 code [0x0000000100000000-0x0000000100000020) r-x 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__text",
"0x0000000000000002 code [0x0000000100000020-0x0000000100000040) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__fake",
"0x0000000000000003 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__encrypted",
"0x0000000000000004 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__tls",
- "0x0000000000000005 data [0x0000000100001000-0x0000000100001333) rw- 0x00001000 0x00000333 0x00000303 c.json.__DATA"
- ])
+ "0x0000000000000005 data [0x0000000100001000-0x0000000100001333) rw- 0x00001000 0x00000333 0x00000303 c.json.__DATA",
+ ],
+ )
error = target.SetSectionLoadAddress(TEXT_section, TEXT_file_addr + slide)
self.assertSuccess(error)
error = target.SetSectionLoadAddress(DATA_section, DATA_file_addr + slide)
self.assertSuccess(error)
|
Sections now support specifying: